package xiaopiya.robot.handler.rss.tool;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gnu.stealthp.rsslib.RSSChannel;
import org.gnu.stealthp.rsslib.RSSException;
import org.gnu.stealthp.rsslib.RSSHandler;
import org.gnu.stealthp.rsslib.RSSItem;
import org.gnu.stealthp.rsslib.RSSParser;

import xiaopiya.robot.handler.rss.exception.RssContentException;

/**
 * @author Ray (ayufox@gmail.com)
 * @version 0.1
 */
public class DefaultRssService implements IRssService
{
	private final static Log LOG = LogFactory.getLog(DefaultRssService.class);

	private long lastGet;

	private Collection<ContentItem> lastPreContent;

	private Collection<ContentItem> lastContent;

	private String link;

	private String channel;

	private int updates = 30 * 1000;

	private IContentItemFilter contentItemFilter;

	public void setUpdateSeconds(int updateSeconds)
	{
		this.updates = updateSeconds * 1000;
	}

	public void setLink(String link)
	{
		this.link = link;
	}

	public void setContentItemFilter(IContentItemFilter contentItemFilter)
	{
		this.contentItemFilter = contentItemFilter;
	}

	public void setChannel(String channel)
	{
		this.channel = channel;
	}

	public void init() throws RssContentException
	{
		new Thread()
		{
			public void run()
			{
				try
				{
					lastPreContent = getLastGet();
				} catch (RssContentException e)
				{
					LOG.error("error when init getLastGet", e);
				}
			}
		}.start();
	}

	public synchronized Collection<ContentItem> getChangeFromLast()
			throws RssContentException
	{
		Collection<ContentItem> last = getLastGet();

		Collection<ContentItem> result = null;
		if (this.lastPreContent == null)
		{
			result = last;
		} else
		{
			result = getChangeFromLast(last);
		}
		this.lastPreContent = last;
		return result;
	}

	private Collection<ContentItem> getChangeFromLast(
			Collection<ContentItem> last)
	{
		Collection<ContentItem> result = new ArrayList<ContentItem>();
		Map<String, ContentItem> map = new HashMap<String, ContentItem>();
		for (ContentItem item : this.lastPreContent)
		{
			map.put(item.getId(), item);
		}
		for (ContentItem item : last)
		{
			if (!map.containsKey(item.getId()))
			{
				result.add(item);
			}
		}
		return result;
	}

	public synchronized Collection<ContentItem> getLastGet()
			throws RssContentException
	{
		// 距离最后一次超过更新时间
		if (System.currentTimeMillis() - this.lastGet > this.updates)
		{
			try
			{
				RSSHandler hand = new RSSHandler();
				RSSParser.parseXmlFile(new URL(this.link), hand, false);

				RSSChannel ch = hand.getRSSChannel();
				LinkedList<RSSItem> lst = ch.getItems();
				Collection<ContentItem> list = new ArrayList<ContentItem>();
				for (RSSItem item : lst)
				{
					list.add(this.contentItemFilter.filter(item));
				}
				this.lastContent = list;
				this.lastGet = System.currentTimeMillis();
			} catch (MalformedURLException e)
			{
				LOG.error("error when get rss", e);

				throw new RssContentException(e);
			} catch (RSSException e)
			{
				LOG.error("error when get rss", e);

				throw new RssContentException(e);
			}
		}
		return this.lastContent;
	}

	public String getChannel()
	{
		return channel;
	}

}
